package com.lhg.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.lhg.constant.Constants;
import com.lhg.framework.es.ESRepository;
import com.lhg.mapper.AdminMapper;
import com.lhg.pojo.dto.AlarmMsg;
import com.lhg.pojo.dto.DeviceDTO;
import com.lhg.pojo.dto.QuotaInfo;
import com.lhg.pojo.entity.User;
import com.lhg.pojo.vo.DeviceQuotaVO;
import com.lhg.pojo.vo.Pager;
import com.lhg.service.DeviceService;
import com.lhg.service.NoticeService;
import com.lhg.service.QuotaService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author 刘华桂
 */
@Service
public class DeviceServiceImpl extends ServiceImpl<AdminMapper, User> implements DeviceService {

    @Autowired
    private ESRepository esRepository;

    @Autowired
    private NoticeService noticeService;

    @Override
    public Pager<DeviceDTO> queryPage(Long page, Long pageSize, String sn, String tag, Integer status) {
        return  esRepository.searchDevice(page,pageSize,sn,tag,status);
    }

    @Autowired
    private QuotaService quotaService;

    @Override
    public Pager<DeviceQuotaVO> queryDeviceQuota(Long page, Long pageSize, String deviceId, String tag, Integer state) {

        //1.查询设备列表

        Pager<DeviceDTO> pager = esRepository.searchDevice(page, pageSize, deviceId, tag, state);


        //2.查询指标列表
        List<DeviceQuotaVO> deviceQuotaVOList= Lists.newArrayList();
        pager.getItems().forEach(deviceDTO -> {
            DeviceQuotaVO deviceQuotaVO=new DeviceQuotaVO();
            BeanUtils.copyProperties(deviceDTO, deviceQuotaVO );
            //查询指标
            List<QuotaInfo> quotaList = quotaService.getLastQuotaList(deviceDTO.getDeviceId());
            deviceQuotaVO.setQuotaList(quotaList);
            deviceQuotaVOList.add(deviceQuotaVO);
        });

        //3.封装返回结果
        Pager<DeviceQuotaVO> pageResult=new Pager(pager.getCounts(),pageSize);
        pageResult.setItems(deviceQuotaVOList);

        return pageResult;
    }

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 根据设备id查询设备
     * @param deviceId
     * @return
     */
    private DeviceDTO findDevice(String deviceId){

        DeviceDTO  deviceDTO = (DeviceDTO)redisTemplate.boundHashOps(Constants.DEVICE_KEY).get(deviceId);
        if(deviceDTO==null){
            deviceDTO = esRepository.searchDeviceById(deviceId);
            refreshDevice(deviceDTO);
        }
        return deviceDTO;
    }

    @Override
    public boolean saveDeviceInfo(DeviceDTO deviceDTO) {
        //查询设备 ，判断开关状态 ，如果是关闭则不处理
        DeviceDTO device= findDevice(deviceDTO.getDeviceId());
        if( device!=null && !device.getStatus() ) {
            return false;
        }

        // 如果当前设备查不到，新增
        if(device==null){
            esRepository.addDevices( deviceDTO );
        }else{
            //如果可以查询到，更新告警信息
            esRepository.updateDevicesAlarm(deviceDTO);
        }
        return true;
    }

    @Override
    public void updateOnLine(String deviceId, Boolean online) {
        //以webclient开头的client为系统前端,monitor开头的是亿可控服务端
        if(deviceId.startsWith("webclient") || deviceId.startsWith("monitor")){
            return;
        }
        //更新数据到es
        DeviceDTO deviceDTO = findDevice(deviceId);
        if(deviceDTO == null) {
            return;
        }

        deviceDTO.setOnline(online);
        esRepository.updateOnline(deviceId,online);
    }

    @Override
    public void disconnectionAlarm(String deviceId) {
        //以web开头的client为系统前端,monitor开头的是亿可控服务端
        if(deviceId.startsWith("webclient") || deviceId.startsWith("monitor")){
            return;
        }
        AlarmMsg alarmMsg = new AlarmMsg();
        alarmMsg.setLevel(1);
        alarmMsg.setAlarmName("设备断网");
        alarmMsg.setDeviceId(deviceId);
        alarmMsg.setOnline(false);
        noticeService.sendDeviceStatusToEmq(alarmMsg);
    }

    @Override
    public boolean setStatus(String sn, Boolean status) {
        DeviceDTO deviceDTO = findDevice(sn);
        if( deviceDTO==null ) {
            return false;
        }
        boolean b = esRepository.updateStatus(sn, status);
        deviceDTO.setStatus(status);
        refreshDevice(deviceDTO);
        return b;
    }

    @Override
    public boolean updateTags(String sn, String tags) {
        DeviceDTO deviceDTO = findDevice(sn);
        if( deviceDTO==null ) {
            return false;
        }
        return esRepository.updateDeviceTag(sn,tags);
    }

    /**
     * 刷新缓存
     * @param deviceDTO
     */
    private void refreshDevice(DeviceDTO deviceDTO ){
        if(deviceDTO==null) {
            return;
        }
        redisTemplate.boundHashOps(Constants.DEVICE_KEY).put(deviceDTO.getDeviceId(),deviceDTO);
    }
}
